package com.hykj.xxltest.config;


import com.hykj.xxltest.base.MsgException;
import com.hykj.xxltest.base.RequiresRole;
import com.hykj.xxltest.model.UserModel;
import com.hykj.xxltest.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 权限配置切入
 */
@Aspect
@Component
public class RequireRoleAspect {

    private static final Logger logger = LoggerFactory.getLogger("RequireRoleAspect");

    @Autowired
    UserService userService;


    /**
     * 定义一个切入点.
     * 解释下：
     * <p>
     * ~ 第一个 * 代表任意修饰符及任意返回值.
     * ~ 第二个 * 定义在web包或者子包
     * ~ 第三个 * 任意方法
     * ~ .. 匹配任意数量的参数.
     */

    @Pointcut("execution(* com.hykj.xxltest.controller.*.*(..)) ")
    public void init() {

    }


   public static Set<Integer> getRequireRoles(RequiresRole requiresRole) {
        String[] sRoles = requiresRole.role().split(",");
        Set<Integer> requireRoles = new HashSet<>();
        for (String role : sRoles) {
            requireRoles.add(Integer.valueOf(role));
        }
        return requireRoles;
    }

    /**
     * 判断用户是否登录，token是否正确 对的话返回userId
     *
     * @return 用户Id
     */
    Integer checkLogin(HttpServletRequest request) {
        Map<String, String[]> map = request.getParameterMap();
        String[] userIds = map.get("userId");
        if (userIds == null) {
            throw new MsgException("登录后才能访问");
        }
        if (StringUtils.isEmpty(userIds[0])) {
            throw new MsgException("登录后才能访问");
        }
        Integer userId = Integer.valueOf(userIds[0]);
        String[] tokens = map.get("token");

        if (tokens == null) {
            throw new MsgException("请传token");
        }
        String token = tokens[0];
        UserModel user = userService.getById(userId);
        if (user == null) {
            throw new MsgException("ID不存在");
        }
        if (user.getStatus() == -1) {
            throw new MsgException(-94, "此账号已被冻结");
        }
        if (user.getStatus() == -10) {
            throw new MsgException(-93, "此账号已被删除");
        }
        RequireRoleAspect.logger.info(token);
        RequireRoleAspect.logger.info(user.getToken());
        if (!token.equals(user.getToken())) {
            throw new MsgException(-95, "登录过期");

        }
        return userId;
    }




    @Before(value = "init() && @annotation(requiresRole)")
    public void requestLimit(JoinPoint joinPoint, RequiresRole requiresRole) {
        if(StringUtils.isEmpty(requiresRole.role())){
            return;
        }

        Set<Integer> requireRoles = getRequireRoles(requiresRole);
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Integer userRole = (Integer) request.getSession().getAttribute("role");
        //判断是否有管理员拥有权限
        if (userRole != null) {
            if (requireRoles.contains(userRole)) {
                return;
            }
        }
        //判断普通注册用户是否能访问
        if (requireRoles.contains(0)) {
            //验证token
            checkLogin(request);

            return;
        }


        throw new MsgException(-94, "无权访问该接口");
    }
}